Skip to main content

Q-3 Alternative: Internal Storage OR Location API (5 Marks)

Questions​

a) How we can store data in internal memory from android application? Discuss its pros and cons. (5 marks)

OR

b) Write a note on android location API and its key features. (5 marks)


Answers​

a) Internal Storage in Android Applications​

Definition​

Internal Storage refers to the private storage space allocated to each Android application on the device's internal memory. This storage is private to the app and inaccessible to other applications.

Methods to Store Data in Internal Storage​

1. Files in Internal Storage

public class InternalStorageHelper {
private Context context;

public InternalStorageHelper(Context context) {
this.context = context;
}

// Write data to internal storage
public void writeToInternalStorage(String filename, String data) {
try {
FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
Toast.makeText(context, "Data saved to internal storage", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context, "Error saving data", Toast.LENGTH_SHORT).show();
}
}

// Read data from internal storage
public String readFromInternalStorage(String filename) {
try {
FileInputStream fis = context.openFileInput(filename);
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
return new String(buffer);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}

// Delete file from internal storage
public boolean deleteFromInternalStorage(String filename) {
return context.deleteFile(filename);
}

// List all files in internal storage
public String[] listInternalFiles() {
return context.fileList();
}

// Check if file exists
public boolean fileExists(String filename) {
File file = new File(context.getFilesDir(), filename);
return file.exists();
}
}

2. Cache Storage

public class CacheStorageHelper {
private Context context;

public CacheStorageHelper(Context context) {
this.context = context;
}

// Write to cache directory
public void writeToCacheDir(String filename, String data) {
try {
File cacheDir = context.getCacheDir();
File file = new File(cacheDir, filename);

FileOutputStream fos = new FileOutputStream(file);
fos.write(data.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}

// Read from cache directory
public String readFromCacheDir(String filename) {
try {
File cacheDir = context.getCacheDir();
File file = new File(cacheDir, filename);

if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
fis.read(buffer);
fis.close();
return new String(buffer);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

// Clear cache
public void clearCache() {
File cacheDir = context.getCacheDir();
if (cacheDir.isDirectory()) {
String[] children = cacheDir.list();
for (String child : children) {
new File(cacheDir, child).delete();
}
}
}
}

3. SharedPreferences (Key-Value Storage)

public class PreferencesHelper {
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;

public PreferencesHelper(Context context, String prefName) {
sharedPreferences = context.getSharedPreferences(prefName, Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
}

// Save data
public void saveString(String key, String value) {
editor.putString(key, value);
editor.apply();
}

public void saveInt(String key, int value) {
editor.putInt(key, value);
editor.apply();
}

public void saveBoolean(String key, boolean value) {
editor.putBoolean(key, value);
editor.apply();
}

// Retrieve data
public String getString(String key, String defaultValue) {
return sharedPreferences.getString(key, defaultValue);
}

public int getInt(String key, int defaultValue) {
return sharedPreferences.getInt(key, defaultValue);
}

public boolean getBoolean(String key, boolean defaultValue) {
return sharedPreferences.getBoolean(key, defaultValue);
}
}

4. SQLite Database

public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "app_database.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_USERS = "users";

public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_USERS + " (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT NOT NULL, " +
"email TEXT UNIQUE NOT NULL)";
db.execSQL(createTable);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_USERS);
onCreate(db);
}

// Insert user
public long insertUser(String name, String email) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("email", email);

long result = db.insert(TABLE_USERS, null, values);
db.close();
return result;
}

// Get all users
public List<User> getAllUsers() {
List<User> users = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_USERS, null);

if (cursor.moveToFirst()) {
do {
User user = new User();
user.setId(cursor.getInt(0));
user.setName(cursor.getString(1));
user.setEmail(cursor.getString(2));
users.add(user);
} while (cursor.moveToNext());
}

cursor.close();
db.close();
return users;
}
}

Complete Example: Text File Manager​

public class MainActivity extends AppCompatActivity {
private InternalStorageHelper storageHelper;
private EditText editTextContent, editTextFilename;
private TextView textViewFilesList;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

storageHelper = new InternalStorageHelper(this);
initViews();
displayFilesList();
}

private void initViews() {
editTextContent = findViewById(R.id.editTextContent);
editTextFilename = findViewById(R.id.editTextFilename);
textViewFilesList = findViewById(R.id.textViewFilesList);

findViewById(R.id.btnSave).setOnClickListener(v -> saveFile());
findViewById(R.id.btnLoad).setOnClickListener(v -> loadFile());
findViewById(R.id.btnDelete).setOnClickListener(v -> deleteFile());
}

private void saveFile() {
String filename = editTextFilename.getText().toString().trim();
String content = editTextContent.getText().toString();

if (!filename.isEmpty() && !content.isEmpty()) {
storageHelper.writeToInternalStorage(filename, content);
displayFilesList();
editTextContent.setText("");
editTextFilename.setText("");
} else {
Toast.makeText(this, "Please enter filename and content", Toast.LENGTH_SHORT).show();
}
}

private void loadFile() {
String filename = editTextFilename.getText().toString().trim();
if (!filename.isEmpty()) {
String content = storageHelper.readFromInternalStorage(filename);
if (content != null) {
editTextContent.setText(content);
} else {
Toast.makeText(this, "File not found", Toast.LENGTH_SHORT).show();
}
}
}

private void deleteFile() {
String filename = editTextFilename.getText().toString().trim();
if (!filename.isEmpty()) {
boolean deleted = storageHelper.deleteFromInternalStorage(filename);
if (deleted) {
Toast.makeText(this, "File deleted", Toast.LENGTH_SHORT).show();
displayFilesList();
editTextFilename.setText("");
} else {
Toast.makeText(this, "Failed to delete file", Toast.LENGTH_SHORT).show();
}
}
}

private void displayFilesList() {
String[] files = storageHelper.listInternalFiles();
StringBuilder filesList = new StringBuilder("Files in Internal Storage:\n");

if (files.length > 0) {
for (String file : files) {
filesList.append("• ").append(file).append("\n");
}
} else {
filesList.append("No files found");
}

textViewFilesList.setText(filesList.toString());
}
}

Pros and Cons of Internal Storage​

Pros (Advantages)​

AdvantageDescription
SecurityPrivate to the app, inaccessible to other apps
No PermissionsNo special permissions required
Always AvailableAlways accessible, not removable
Automatic CleanupAutomatically deleted when app is uninstalled
Fast AccessFaster than external storage
ReliableAlways mounted and available

Cons (Disadvantages)​

DisadvantageDescription
Limited SpaceLimited by device's internal storage capacity
Not ShareableCannot be shared with other apps directly
User InaccessibleUsers cannot directly access files
Backup IssuesMay not be included in device backups
Storage PressureUses device's main storage space
Size LimitationsNot suitable for large files or media

Best Practices for Internal Storage​

  1. Use Appropriate Storage Type:

    • Small data: SharedPreferences
    • Structured data: SQLite
    • Files: Internal file storage
    • Temporary data: Cache directory
  2. Handle Storage Exceptions:

    try {
    // Storage operations
    } catch (IOException e) {
    // Handle storage errors gracefully
    }
  3. Check Available Space:

    public long getAvailableInternalMemorySize() {
    File path = Environment.getDataDirectory();
    StatFs stat = new StatFs(path.getPath());
    long blockSize = stat.getBlockSize();
    long availableBlocks = stat.getAvailableBlocks();
    return availableBlocks * blockSize;
    }
  4. Clean Up Resources:

    // Always close streams
    try (FileOutputStream fos = openFileOutput(filename, MODE_PRIVATE)) {
    fos.write(data.getBytes());
    } catch (IOException e) {
    e.printStackTrace();
    }

b) Android Location API and Key Features​

Definition​

Android Location API provides access to location-based services, allowing applications to determine the device's geographic location and track location changes.

Key Components​

1. LocationManager: Core system service for location access 2. Location Providers: GPS, Network, Passive providers 3. LocationListener: Interface for receiving location updates 4. Geocoder: Convert between addresses and coordinates

Required Permissions​

<!-- Coarse location (network-based) -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<!-- Fine location (GPS) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- Background location (Android 10+) -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

Location Providers​

1. GPS Provider:

  • Most accurate
  • Requires clear sky view
  • High battery consumption
  • Slower first fix

2. Network Provider:

  • Uses Wi-Fi and cellular towers
  • Faster location fix
  • Lower accuracy
  • Less battery consumption

3. Passive Provider:

  • Uses location requested by other apps
  • No additional battery drain
  • Unpredictable updates

Implementation Example​

public class LocationHelper implements LocationListener {
private LocationManager locationManager;
private Context context;
private LocationCallback callback;

public interface LocationCallback {
void onLocationReceived(Location location);
void onLocationError(String error);
}

public LocationHelper(Context context, LocationCallback callback) {
this.context = context;
this.callback = callback;
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}

public void requestLocationUpdates() {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {

// Check if GPS is enabled
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
10000, // 10 seconds
10, // 10 meters
this
);
}

// Also request network location
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
10000,
10,
this
);
}
} else {
callback.onLocationError("Location permission not granted");
}
}

public void getLastKnownLocation() {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {

Location gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

// Choose the most recent and accurate location
Location bestLocation = getBetterLocation(gpsLocation, networkLocation);

if (bestLocation != null) {
callback.onLocationReceived(bestLocation);
} else {
callback.onLocationError("No last known location available");
}
}
}

private Location getBetterLocation(Location location1, Location location2) {
if (location1 == null) return location2;
if (location2 == null) return location1;

// Check which is more recent
if (location1.getTime() > location2.getTime()) {
return location1;
} else {
return location2;
}
}

public void stopLocationUpdates() {
if (locationManager != null) {
locationManager.removeUpdates(this);
}
}

// LocationListener methods
@Override
public void onLocationChanged(Location location) {
callback.onLocationReceived(location);
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// Handle provider status changes
}

@Override
public void onProviderEnabled(String provider) {
// Handle provider enabled
}

@Override
public void onProviderDisabled(String provider) {
callback.onLocationError("Location provider disabled: " + provider);
}
}

Usage in Activity​

public class MainActivity extends AppCompatActivity implements LocationHelper.LocationCallback {
private LocationHelper locationHelper;
private TextView locationText;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

locationText = findViewById(R.id.locationText);
locationHelper = new LocationHelper(this, this);

findViewById(R.id.btnGetLocation).setOnClickListener(v -> getLocation());
findViewById(R.id.btnStartTracking).setOnClickListener(v -> startLocationTracking());
findViewById(R.id.btnStopTracking).setOnClickListener(v -> stopLocationTracking());
}

private void getLocation() {
if (checkLocationPermissions()) {
locationHelper.getLastKnownLocation();
} else {
requestLocationPermissions();
}
}

private void startLocationTracking() {
if (checkLocationPermissions()) {
locationHelper.requestLocationUpdates();
} else {
requestLocationPermissions();
}
}

private void stopLocationTracking() {
locationHelper.stopLocationUpdates();
}

@Override
public void onLocationReceived(Location location) {
String locationInfo = String.format(
"Latitude: %.6f\nLongitude: %.6f\nAccuracy: %.2f meters\nProvider: %s\nTime: %s",
location.getLatitude(),
location.getLongitude(),
location.getAccuracy(),
location.getProvider(),
new Date(location.getTime()).toString()
);

locationText.setText(locationInfo);

// Optionally, reverse geocode to get address
reverseGeocode(location);
}

@Override
public void onLocationError(String error) {
locationText.setText("Error: " + error);
Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
}

private void reverseGeocode(Location location) {
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(
location.getLatitude(), location.getLongitude(), 1);

if (addresses != null && !addresses.isEmpty()) {
Address address = addresses.get(0);
String addressText = address.getAddressLine(0);
locationText.append("\nAddress: " + addressText);
}
} catch (IOException e) {
e.printStackTrace();
}
}

private boolean checkLocationPermissions() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
}

private void requestLocationPermissions() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_LOCATION_PERMISSION);
}
}

Key Features of Location API​

1. Location Accuracy: Different providers offer varying accuracy levels 2. Battery Optimization: Choose appropriate update intervals and distances 3. Geocoding: Convert addresses to coordinates and vice versa 4. Geofencing: Monitor entry/exit of geographical regions 5. Location-based Services: Enable location-aware applications 6. Background Location: Continue tracking in background (with proper permissions)

Common Applications​

  • Navigation Apps: GPS navigation and route planning
  • Weather Apps: Location-based weather information
  • Social Media: Location tagging and check-ins
  • Fitness Apps: Track running/walking routes
  • Retail Apps: Store locators and proximity offers
  • Security Apps: Device tracking and find-my-device features